package top.easyblog.core.service;


import eu.bitwalker.useragentutils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.easyblog.core.atomic.AtomicMappingVisitRecordService;
import top.easyblog.core.converter.BeanMapper;
import top.easyblog.core.dao.auto.model.MappingVisitRecord;
import top.easyblog.core.mq.RedisMessageProducer;
import top.easyblog.core.mq.RedisMessageTopic;
import top.easyblog.core.mq.bean.MappingVisitMessage;
import top.easyblog.core.support.filter.TransformContext;
import top.easyblog.core.util.EncryptUtils;
import top.easyblog.core.util.JsonUtils;
import top.easyblog.core.util.UserAgentUtils;

import java.util.Optional;

import static top.easyblog.core.support.filter.TransformContext.*;

/**
 * @author: frank.huang
 * @date: 2023-12-30 17:35
 */
@Slf4j
@Service
public class MappingVisitRecordService {

    @Autowired
    private AtomicMappingVisitRecordService atomicMappingVisitRecordService;

    @Autowired
    private RedisMessageProducer redisMessageProducer;

    @Autowired
    private BeanMapper beanMapper;


    public void saveMappingVisitRecord(MappingVisitMessage message) {
        String uniqueIdentity = EncryptUtils.SHA256(message.getClientIp() + "-" + message.getUserAgent());
        MappingVisitRecord mappingVisitRecord = beanMapper.convertMappingVisitMessage2MappingVisitRecord(message);
        mappingVisitRecord.setUniqueIdentity(uniqueIdentity);

        if (StringUtils.isNotBlank(message.getUserAgent())) {
            mappingVisitRecord.setUserAgent(message.getUserAgent());
            try {
                UserAgent userAgent = UserAgent.parseUserAgentString(message.getUserAgent());
                OperatingSystem operatingSystem = userAgent.getOperatingSystem();
                Optional.ofNullable(operatingSystem).ifPresent(x -> {
                    mappingVisitRecord.setOsType(x.getName());
                    mappingVisitRecord.setOsVersion(x.getName());
                    Optional.ofNullable(x.getDeviceType()).ifPresent(deviceType -> {
                        mappingVisitRecord.setDeviceType(deviceType.getName());
                        if (DeviceType.MOBILE == deviceType) {
                            UserAgentUtils.UserAgentExtractResult result
                                    = UserAgentUtils.extractSystemType(message.getUserAgent());
                            mappingVisitRecord.setPhoneType(result.getPhoneType());
                            mappingVisitRecord.setOsType(result.getSystemType());
                            mappingVisitRecord.setOsVersion(result.getSystemVersion());
                        }
                    });
                });
                Browser browser = userAgent.getBrowser();
                Optional.ofNullable(browser).ifPresent(x -> mappingVisitRecord.setBrowserType(x.getGroup().getName()));
                Version browserVersion = userAgent.getBrowserVersion();
                Optional.ofNullable(browserVersion).ifPresent(x -> mappingVisitRecord.setBrowserVersion(x.getVersion()));
            } catch (Exception e) {
                log.error("解析MappingVisit中的UserAgent异常:{}", JsonUtils.toJSONString(message), e);
            }
        }
        atomicMappingVisitRecordService.insertOne(mappingVisitRecord);
    }


    public void sendMappingVisitMessage(TransformContext context) {
        MappingVisitMessage message = MappingVisitMessage.builder()
                .clientIp(context.getParam(PARAM_CLIENT_IP_KEY))
                .compressionCode(context.getCompressionCode())
                .userAgent(context.getParam(PARAM_UA_KEY))
                .tinyUrl(context.getParam(PARAM_SHORT_URL_KEY))
                .sourceUrl(context.getParam(PARAM_LONG_URL_KEY))
                .transformStatus(context.getTransformStatus().getValue())
                .timestamp(System.currentTimeMillis())
                .build();

        redisMessageProducer.sendRedisMessage(JsonUtils.toJSONString(message), RedisMessageTopic.URL_MAPPING_VISIT);
    }


}
